package cn.bqjr.eily.samples.utils;

import cn.bqjr.eily.samples.entity.po.User;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;

import java.util.Collection;

public class ShiroUtils extends SecurityUtils {

    private static final String USER_ENTITY = "userEntity";

    public static void setLocalUser(Session session, User user) {
        session.setAttribute(USER_ENTITY, user);
    }

    /**
     * 获取当前登录用户实体类
     *
     * @return
     */
    public static User getLocalUser(Session session) {
        Object obj = session.getAttribute(USER_ENTITY);
        return null == obj ? null : (User) obj;
    }

    public static void setLocalUser(User user) {
        SecurityUtils.getSubject().getSession().setAttribute(USER_ENTITY, user);
    }

    /**
     * 获取当前登录用户实体类
     *
     * @return
     */
    public static User getLocalUser() {
        Object obj = SecurityUtils.getSubject().getSession().getAttribute(USER_ENTITY);
        return null == obj ? null : (User) obj;
    }

    /**
     * 获取当前登录用户loginId
     *
     * @return
     */
    public static String getLocalLoginId() {
        User user = getLocalUser();
        return null == user ? null : user.getLoginId();
    }

    /**
     * 获取当前登录用户userId
     *
     * @return
     */
    public static Long getLocalUserId() {
        User user = getLocalUser();
        return null == user ? null : user.getUserId();
    }

    /**
     * 用户登出
     */
    public static void logout() {
        SecurityUtils.getSubject().logout();
    }

    public static String getSessionId() {
        return SecurityUtils.getSubject().getSession().getId().toString();
    }

    public static DefaultWebSessionManager getSessionManager() {
        DefaultWebSecurityManager securityManager =
                (DefaultWebSecurityManager) SecurityUtils.getSecurityManager();
        DefaultWebSessionManager sessionManager =
                (DefaultWebSessionManager) securityManager.getSessionManager();
        return sessionManager;
    }

    public static SessionDAO getSessionDAO() {
        return getSessionManager().getSessionDAO();
    }

    public static Collection<Session> getActiveSessions() {
        //获取当前已登录的用户session列表
        return getSessionDAO().getActiveSessions();
    }

    /**
     * 删除指定loginId的session - 踢除在线用户
     *
     * @param loginId
     */
    public static void deleteSessionByLoginId(String loginId, String companyId) {
        Collection<Session> sessions = getActiveSessions();
        for (Session session : sessions) {
            User user = getLocalUser(session);
            if (null != user
                    && loginId.equals(user.getLoginId())
                    && companyId.equals(user.getCompanyId())) {
                getSessionDAO().delete(session);
            }
        }
    }

    /**
     * 删除指定userId的session - 踢除在线用户
     *
     * @param userId
     */
    public static void deleteSessionByUserId(Long userId) {
        Collection<Session> sessions = getActiveSessions();
        sessions.forEach(session -> {
            User sessionUser = getLocalUser(session);
            if (null != sessionUser && userId.equals(sessionUser.getUserId())) {
                ShiroUtils.getSessionManager()
                          .getSessionListeners()
                          .stream()
                          .forEach(listener -> listener.onStop(session));
                getSessionDAO().delete(session);
            }
        });
    }

    /**
     * 剔除同帐号的其它用户会话
     */
    public static void kickoutOtherSameUser() {
        String sessionId = getSessionId();
        Collection<Session> sessions = getActiveSessions();
        for (Session session : sessions) {
            //过滤本机session
            if (sessionId.equals(session.getId().toString())) continue;
            User user = getLocalUser(session);
            if (null != user && getLocalUserId().equals(user.getUserId())) {
                ShiroUtils.getSessionManager()
                          .getSessionListeners()
                          .stream()
                          .forEach(listener -> listener.onStop(session));
                getSessionDAO().delete(session);
            }
        }
    }
}
